package com.ruoyi.web.controller.system;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.prop.UserProperties;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.service.ISysOssService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import jdk.nashorn.internal.objects.annotations.Getter;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.aspectj.weaver.loadtime.Aj;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.net.www.http.PosterOutputStream;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * @author 最爱喝兽奶
 * @create 2022/6/13
 **/
@RestController
@RequestMapping("/system/oss")
public class  SysOssController extends BaseController {

    @Autowired
    private ISysOssService sysOssService;

    @Autowired
    private UserProperties userProperties;

    @ApiOperation("查询oss对象列表")
    @GetMapping("/query/{ids}")
    public AjaxResult queryOssByIds(@PathVariable("ids") String ids) {
        if (StringUtils.isNotBlank(ids)) {
            String[] split = ids.split(",");
            List<String> list = new ArrayList<>();
            for (String s : split) {
                try {
                    list.add(s);
                } catch (Exception e) {
                    continue;
                }
            }
            return AjaxResult.success(sysOssService.queryListByIds(list));
        }
        return AjaxResult.error();
    }

    @ApiOperation("传入ossid查询oss对象")
    @GetMapping("/query")
    public AjaxResult queryOssById(@RequestParam("id") String id) {
        try {
            SysOss sysOss = sysOssService.queryById(id);
            return AjaxResult.success(sysOss);
        }catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @ApiOperation("上传OSS对象存储")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件", dataTypeClass = File.class, required = true),
    })
    @PostMapping("/upload")
    public AjaxResult upload(@RequestParam("file")MultipartFile file) {
        if (null == file) {
            return AjaxResult.error("上传文件不能为空", null);
        }
        try {
            SysOss oss = sysOssService.upload(file);
            return AjaxResult.success(oss);
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @ApiOperation("传入ossId删除文件")
    @GetMapping("/delete/{ossId}")
    public AjaxResult deleteFile(@PathVariable("ossId") String[] ossIds) {
        Boolean ans = sysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true);
        if (ans) {
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }
    }

    @PostMapping("/upload/bigFile")
    public AjaxResult uploadBigFile(
            // 当前分片
            @RequestParam(value = "chunk", required = false) Integer chunk,
            // 总分片数
            @RequestParam(value = "chunks", required = false) Integer chunks,
            // 文件名
            @RequestParam("name") String name,
            // 时间戳，用于去重
            @RequestParam("guid") String guid,
            // 文件的二进制信息
            @RequestParam("file") MultipartFile file) throws IOException {
        // 文件存储的临时路径
        // 如果名称和分片数不为空，就将文件信息存储至本地硬盘
        File tempFile = sysOssService.createTempFile(name, chunk, chunks, userProperties.getFilePath());
        if (!tempFile.exists()) {
            // 如果当前文件不存在，就直接上传
            FileUtils.writeToLocal(file.getInputStream(), tempFile);
        }
        return AjaxResult.success();
    }

    @GetMapping("/upload/bigFile/finish")
    public AjaxResult uploadBigFileFinish(@RequestParam("orgName") String orgName) throws IOException {
        String tempName = orgName;
        Integer chunks = sysOssService.getChunks(tempName);
        PosterOutputStream posterOutputStream = new PosterOutputStream();
//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        if (null == chunks) {
            // 如果总分片数为0
            File file = sysOssService.createTempFile(tempName, null, null, userProperties.getFilePath());
//            bos.write(FileUtils.readByteFromFile(file));
            posterOutputStream.write(Objects.requireNonNull(FileUtils.readByteFromFile(file)));
            FileUtils.deleteFile(sysOssService.createTempFileName(tempName, null));
        }else {
            for (int i = 0; i < chunks; i++) {
                File file = sysOssService.createTempFile(tempName, i, chunks, userProperties.getFilePath());
                if (!file.exists()) {
                    throw new RuntimeException("读取了错误的分片");
                }
//                bos.write(Objects.requireNonNull(FileUtils.readByteFromFile(file)));
                posterOutputStream.write(Objects.requireNonNull(FileUtils.readByteFromFile(file)));
                file.deleteOnExit();
            }
        }
        int lastPoint = orgName.lastIndexOf('.');
        String filename = orgName.substring(0, lastPoint);
        String suffix = orgName.substring(lastPoint);
        SysOss upload = sysOssService.upload(posterOutputStream.toByteArray(), filename, suffix);
        return AjaxResult.success(upload);
    }

    @ApiOperation("下载模板文件")
    @GetMapping("/download")
    public void downloadFile(@RequestParam(value = "templateFile", required = true) String templateFile,
                                     HttpServletResponse response) throws IOException {
        byte[] data = sysOssService.download(templateFile);
        genCode(response, data);
    }

    /**
     * 生成文件
     */
    private void genCode(HttpServletResponse response, byte[] data) throws IOException
    {
        response.reset();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=\"templateFile.xls\"");
//        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IOUtils.write(data, response.getOutputStream());
    }
}
